import { setGlobal } from "@swda/utils";
import { generateRecipe } from "./synthesisLogic.js";
import * as utils from "./synthesisUtils.js";

let SWDAWindowManager = {};
SWDAWindowManager.commandSynthesisResultButtonImage =
  "MenuButton_SynthesisResult";

function SWDA_Window_SynthesisResult() {
  this.initialize.apply(this, arguments);
}

SWDA_Window_SynthesisResult.prototype = Object.create(
  SWDA_Window_Command_4Arrows.prototype
);
SWDA_Window_SynthesisResult.prototype.constructor = SWDA_Window_SynthesisResult;

SWDA_Window_SynthesisResult.prototype.initialize = function (
  x,
  y,
  width,
  height
) {
  this.clearSucessFlag();
  SWDA_Window_Command_4Arrows.prototype.initialize.call(this, x, y);

  this.initData();
  this.x = x;
  this.y = y;
  this.setWidthAndHeight(width, height);
  this.refresh();
  this.createButtons(
    SWDAWindowManager.commandSynthesisResultButtonImage,
    Graphics.boxWidth / 2 - 2 * x - 2,
    570 - 2 * y - 18
  );

  this.deselect();
  this.deactivate();
  this.opacity = 255;
  this.contentsOpacity = 255;

  this.createNameWindow();
  this.createPreviewWindow();
  this.cursorOpacity = 0;

  this._actorSprites = []
};

SWDA_Window_SynthesisResult.prototype.createPreviewWindow = function () {
  const rect = this.resultPreviewRect();
  const x = rect.x + this.standardPadding();
  const y = rect.y;
  this._viewerWindow = new Window_ItemViewer(x, y, 240, 334);
  this.addChild(this._viewerWindow);
};

SWDA_Window_SynthesisResult.prototype.createNameWindow = function () {
  const rect = this.resultNameRect();
  const x = rect.x + this.standardPadding();
  const y = rect.y;
  const w = rect.width;
  const h = rect.height;

  this._nameWindow = new Window_Base(x, y, w, h);
  this.addChild(this._nameWindow);
};

SWDA_Window_SynthesisResult.prototype.setWidthAndHeight = function (
  width,
  height
) {
  this.width = width;
  this.height = height;
};

SWDA_Window_SynthesisResult.prototype.makeCommandList = function () {
  this.addCommand("", "", false);
  this.addCommand(
    CP.SynthesisManager.UI_SYNTHESIS_COMMAND_NAME,
    "synthesis",
    this.canExecSynthesis()
  );
  this.addCommand("", "", false);
  this.addCommand(CP.SynthesisManager.UI_CANCEL_COMMAND_NAME, "cancel");
};

SWDA_Window_SynthesisResult.prototype.isValidLevel = function () {
  const recipetFormulaInfo = this.getFormulaInfo();
  if (!recipetFormulaInfo) return false;
  const recipetResult = generateRecipe(recipetFormulaInfo);
  const { finalProduce } = recipetResult;

  const level = utils.getCatchLevelByItemMeta(finalProduce.meta);
  const actorLevel = $gameActors.actor(1).level;
  return level <= actorLevel + 5;
};

// 能否合成
SWDA_Window_SynthesisResult.prototype.canExecSynthesis = function () {
  const isValidLevel = this.isValidLevel();
  if (!isValidLevel) return false;

  return (
    this.hasSynthesisResult() &&
    this.meetsSynthesisCondition(
      this._recipeItem1,
      this._recipeItem2,
      this._synthesisResult
    )
  );
};

SWDA_Window_SynthesisResult.prototype.hasSynthesisResult = function () {
  return !!this._recipeItem1 && !!this._recipeItem2 && !!this._synthesisResult;
};

SWDA_Window_SynthesisResult.prototype.meetsSynthesisCondition = function (
  recipe1,
  recipe2,
  produce
) {
  try {
    return CP.SynthesisManager.SYNTHESIS_CONDITION.call(
      this,
      false,
      recipe1,
      recipe2,
      produce
    );
  } catch (err) {
    console.error(err);
    return false;
  }
};

SWDA_Window_SynthesisResult.prototype.initData = function () {
  this.setRecipeItems(null, null);
  this.setSynthesisResult(null);
};

SWDA_Window_SynthesisResult.prototype.setRecipeItems = function (item1, item2) {
  this._recipeItem1 = item1;
  this._recipeItem2 = item2;
};

SWDA_Window_SynthesisResult.prototype.setSynthesisResult = function (result) {
  this._synthesisResult = result;
};

SWDA_Window_SynthesisResult.prototype.setFormulaInfo = function (meta = {}) {
  this._formulaInfo = meta;
};

SWDA_Window_SynthesisResult.prototype.getFormulaInfo = function () {
  return this._formulaInfo;
};

//index从1到2
SWDA_Window_SynthesisResult.prototype.recipeItem = function (index) {
  if (index === 1) return this._recipeItem1;
  if (index === 2) return this._recipeItem2;
  return null;
};

SWDA_Window_SynthesisResult.prototype.synthesisResult = function () {
  this._resultSuccess = this.meetsSynthesisResult();
  if (this._resultSuccess) return this.successfulSynthesisResult();
  else return this.failureResult(this._recipeItem1, this._recipeItem2);
  //return this._synthesisResult;
};

SWDA_Window_SynthesisResult.prototype.updateHelp = function () {
  this.setHelpWindowItem(this._synthesisResult);
  if (!this.isValidLevel()) {
    this._helpWindow.setText("等级不足！无法炼成！");
  }
};

// 【Draw】======================================================================
SWDA_Window_SynthesisResult.prototype.drawAllItems = function () {
  Window_Selectable.prototype.drawAllItems.call(this);
  this.drawResult();
};

SWDA_Window_SynthesisResult.prototype.drawResult = function () {
  if (!!this.hasSynthesisResult()) {
    this._actorSprites.forEach(element => {
      this.removeChild(element)
    });
    const item = this._synthesisResult;
    this.drawResultItem(this.resultPreviewRect(), item);
    this.drawResultEnemyInfo(this.resultEnemyInfoRect(), this.enemy());
    this.drawResultEquipInfo(this.resultEquipInfoRect(), item);
      
  }
};
SWDA_Window_SynthesisResult.prototype.enemy = function () {
  const item = this._synthesisResult;
  if (!item.useItemId) return false;
  if (!$dataItems[item.useItemId].petAddedInfo) return false;
  const enemy = new Game_Enemy(
    $dataItems[item.useItemId].petAddedInfo.enemyId,
    0,
    0
  );
  return enemy;
};

SWDA_Window_SynthesisResult.prototype.drawResultItem = function (rect, item) {
  this.drawItemPreview(rect, item);
  this.drawResultName(item);
};

SWDA_Window_SynthesisResult.prototype.drawResultEnemyInfo = function (
  rect,
  enemy
) {

  const lineHeight = this.smallerLineHeight();
  let x = rect.x + 12;
  let y = rect.y + lineHeight;
  let d = 48;
  let width = (rect.width - d) / 2;

  if (!this.enemy()){
    this.setSmallerFont();
    this.changeTextColor(this.systemColor());
    this.drawText("[无法召唤]", x, y);
    this.resetFontSettings();
    return;
  }
    
  // 小标题
  this.setSmallerFont();
  this.changeTextColor(this.systemColor());
  this.drawText("[召唤信息]", x, y);
  this.resetTextColor();
  y += lineHeight * 2;

  // 绘制 敌人核心信息（命仙体）
  this.setSmallerFont();
  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.hp, x, y);
  this.resetTextColor();
  this.drawText(enemy.hp, x, y, width, "right");
  y += lineHeight;

  this.setSmallerFont();
  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.mp, x, y);
  this.resetTextColor();
  this.drawText(enemy.mp, x, y, width, "right");
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.tp, x, y);
  this.resetTextColor();
  this.drawText(enemy.tp, x, y, width, "right");

  y += lineHeight;

  // 属性
  const infoArray = [1, 2, 3];
  for (let i = 0; i < infoArray.length; ++i) {
    this.drawEnemyElementData(infoArray[i], x, y, width);
    y += lineHeight;
  }

  // 第二列
  x = rect.x + 12 + width + d;
  y = rect.y + lineHeight * 3;

  // 绘制种族
  this.setSmallerFont();
  this.changeTextColor(this.systemColor());
  this.drawText("种族", x, y);
  this.resetTextColor();
  this.drawTextEx(
    this.enemyClassText(enemy._classId)[0],
    x + width - 8 - 26 - this.textWidth(this.enemyClassText(enemy._classId)[1]),
    y
  );
  this.setSmallerFont();
  this.drawText(this.enemyClassText(enemy._classId)[1], x, y, width, "right");
  y += lineHeight;

  // 绘制 敌人基础数值
  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(2), x, y);
  this.resetTextColor();
  this.drawText(enemy.atk, x, y, width, "right");
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(3), x, y);
  this.resetTextColor();
  this.drawText(enemy.def, x, y, width, "right");
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(4), x, y);
  this.resetTextColor();
  this.drawText(enemy.mat, x, y, width, "right");
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(5), x, y);
  this.resetTextColor();
  this.drawText(enemy.mdf, x, y, width, "right");
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(6), x, y);
  this.resetTextColor();
  this.drawText(enemy.agi, x, y, width, "right");

  /* 
   this.changeTextColor(this.systemColor());
   this.drawText(TextManager.param(7), x, y);
   this.resetTextColor();
   this.drawText(enemy.luk, x, y, width, 'right');
   */

  y += lineHeight * 2;

  // 技能
  x = rect.x + 12;
  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.skill, x, y);
  this.resetTextColor();
  y += lineHeight;

  let enemyData =
    $dataEnemies[
      $dataItems[this._synthesisResult.useItemId].petAddedInfo.enemyId
    ];
  let skillCount = 0;
  for (let i = 0; i < enemyData.actions.length; i++) {
    if (enemyData.actions[i].skillId > 6) {
      const skill = $dataSkills[enemyData.actions[i].skillId];
      if (!DataManager.isAttack(skill)) {
        this.drawItemName(skill, x, y);
        y += lineHeight;
        skillCount++;
      }
    }
  }

  if (skillCount <= 0) {
    this.drawText("无", x, y);
  }

  // 攻击特性
  x = rect.x + 12 + width + d;
  y = rect.y + lineHeight * 10;
  this.changeTextColor(this.systemColor());
  this.drawText("攻击附加", x, y);
  this.resetTextColor();
  y += lineHeight 
  this.drawStates(enemy.attackStates(), x, y);
  this.resetFontSettings();
};

SWDA_Window_SynthesisResult.prototype.drawStates = function(states, x, y){
  const length = states.length;
  const d = 24;
  let total = 0;
  for(let i = 0; i < length; i++){
      let stateiconId = $dataStates[states[i]].iconIndex;
      if(stateiconId > 0){
          this.drawTextEx('\\i['+ stateiconId +']', x-6, y);
          x += d;
          total++;
      }
  }
  if(total==0)
      this.drawText('无', x, y);
}


SWDA_Window_SynthesisResult.prototype.drawResultEquipInfo = function (
  rect,
  item
) {
  const lineHeight = this.smallerLineHeight();
  let x = rect.x + 12;
  let y = rect.y + lineHeight;
  let width = rect.width - 24;
  
  if (!DataManager.isArmor(item)){
    this.setSmallerFont();
    this.changeTextColor(this.systemColor());
    this.drawText("[无法装备]", x, y);
    this.resetFontSettings();
    return;
  }
    
  if (item.atypeId == 0){
    this.setSmallerFont();
    this.changeTextColor(this.systemColor());
    this.drawText("[无法装备]", x, y);
    this.resetFontSettings();
    return;
  }
    

  // 小标题
  this.setSmallerFont();
  this.changeTextColor(this.systemColor());
  this.drawText("[装备信息]", x, y);
  this.resetTextColor();
  y += lineHeight * 2;

  // 绘制 敌人核心信息（命仙体）
  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(0), x, y);// 生命上限
  this.drawResultEquipParameter(item.params[0], x, y, width);
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(1), x, y);// 仙术上限
  this.drawResultEquipParameter(item.params[1], x, y, width);
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText("体力上限", x, y); // 体力上限
  this.drawResultEquipParameter(item.tpPlus, x, y, width);
  y += lineHeight;

  // 绘制 敌人基础数值
  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(2), x, y);// 物攻
  this.drawResultEquipParameter(item.params[2], x, y, width);
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(3), x, y); // 物防
  this.drawResultEquipParameter(item.params[3], x, y, width);
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(4), x, y);// 仙攻
  this.drawResultEquipParameter(item.params[4], x, y, width);
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(5), x, y);// 仙防
  this.drawResultEquipParameter(item.params[5], x, y, width);
  y += lineHeight;

  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(6), x, y);// 敏捷
  this.drawResultEquipParameter(item.params[6], x, y, width);
  y += lineHeight;

  /*
  this.changeTextColor(this.systemColor());
  this.drawText(TextManager.param(7), x, y);
  this.drawResultEquipParameter(item.params[5], x, y, width);
  y += lineHeight;
*/
  y += lineHeight;
  this.changeTextColor(this.systemColor());
  this.drawText('可装备角色', x, y);  // 敏捷

  // 可装备角色

  let dx = x + width - 24;
  let dy = y + 24;
  this._actorSprites = [];
  let bitmapName = '';
  for(let actorId = 4; actorId >=1; --actorId){
    let actor = $gameActors.actor(actorId);
    let canEquip = actor.canEquip(item) && actor.equipSlots().includes(item.etypeId);

    if (canEquip){
      let headSprite = new Sprite();
      bitmapName = 'head' + actor.actorId() + ((actor.actorId()==1 && $gameSwitches.value(299)) ? "a" : "");
      headSprite.bitmap = ImageManager.loadBitmap('img/system/actors/', bitmapName);
      headSprite.x = dx;
      headSprite.y = dy;
      dx -= 32;
      this._actorSprites.push(headSprite);
      this.addChild(this._actorSprites[this._actorSprites.length-1]);
    }
  }

};
SWDA_Window_SynthesisResult.prototype.drawResultEquipParameter = function (
  param,
  x,
  y,
  width
) {
  this.setSmallerFont();
  this.changeTextColor(this.paramchangeTextColor(param));
  if (param > 0) {
    this.drawText("+" + param, x, y, width, "right");
  } else if (param < 0) {
    this.drawText(param, x, y, width, "right");
  } else {
    this.drawText("—", x, y, width, "right");
  }
  this.resetTextColor();
};

SWDA_Window_SynthesisResult.prototype.drawEnemyElementData = function (
  eleId,
  dx,
  dy,
  dw
) {
  const enemy = this.enemy();
  const eleName = $dataSystem.elements[eleId];
  let eleRate = enemy.elementRate(eleId);

  this.setSmallerFont();
  this.changeTextColor(this.systemColor());
  this.drawText(eleName, dx, dy);
  this.resetTextColor();
  let eleText = "";
  if (eleRate > 1) {
    eleText = "损";
    eleRate -= 1;
    this.changeTextColor("#ff4d00");
  } else if (eleRate == 1) {
    eleText = "—";
    this.changeTextColor("#fbdb45");
  } else if (eleRate >= 0) {
    eleText = "抗";
    eleRate -= 1;
    this.changeTextColor("#59ba8e");
  } else {
    eleText = "吸";
    this.changeTextColor("#65cbff");
  }

  let text = eleText;
  /*
  if (eleRate == 1) {
    text = eleText;
  } else {
    text =
      eleText +
      Math.abs(Math.round(eleRate * 100)).toFixed(Yanfly.Param.StatusEleDec) +
      "%";
  }
  */
  this.drawText(text, dx, dy, dw, "right");

  this.resetFontSettings();
  
};

SWDA_Window_SynthesisResult.prototype.drawResultName = function (item) {
  this._nameWindow.contents.clear();
  this._nameWindow.resetFontSettings();
  this._nameWindow.resetTextColor();

  const x = 0;
  const y = 0;
  const width = this._nameWindow.contents.width;
  let level = 0;

  const iconBoxWidth = Window_Base._iconWidth;
  this._nameWindow.resetFontSettings();
  this._nameWindow.resetTextColor();
  this._nameWindow.drawIcon(item.iconIndex, x, y + 2);
  this._nameWindow.drawText(
    item.name.split("（")[0],
    x + iconBoxWidth,
    y,
    width,
    "left"
  );

  //y += this.lineHeight();
  level = item.catchLevel;
  if (item.useItemId) {
    if ($dataItems[item.useItemId].petAddedInfo) {
      level =
        $dataEnemies[$dataItems[item.useItemId].petAddedInfo.enemyId]
          .catchLevel;
    }
  }

  const width2 = width - this._nameWindow.textWidth(TextManager.levelA) - 4;
  this._nameWindow.setSmallerFont();
  this._nameWindow.drawText(level, x, y, width2, "right");
  this._nameWindow.resetFontSettings();
  this._nameWindow.drawText(TextManager.levelA, x, y, width, "right");
};

SWDA_Window_SynthesisResult.prototype.drawNoRecipeText = function (rect) {
  const width = this.textWidth(CP.SynthesisManager.UI_NO_RECIPE_TEXT);
  const offsetX = Math.round((rect.width - width) / 2);
  const offsetY = Math.round(rect.height / 2);

  this.resetFontSettings();
  this.resetTextColor();

  this.drawText(
    CP.SynthesisManager.UI_NO_RECIPE_TEXT,
    rect.x + offsetX,
    rect.y + offsetY,
    width
  );
};

SWDA_Window_SynthesisResult.prototype.drawItemPreview = function (rect, item) {
  if (!item) return;
  this._viewerWindow.showView(item);
};
// 【Rect】======================================================================

SWDA_Window_SynthesisResult.prototype.itemRect = function (index) {
  let rect = Window_Selectable.prototype.itemRect.call(this, index + 1);
  rect.x = 0;
  rect.y = 0;
  rect.width = 0;
  rect.height = 0;
  return rect;
};

SWDA_Window_SynthesisResult.prototype.resultPreviewRect = function () {
  let rect = new Rectangle();
  rect.x = this.contents.width / 2 - 120;
  rect.y =
    this.resultNameRect().y +
    this.resultNameRect().height +
    this.standardPadding();
  rect.width = 240;
  rect.height = this.contents.height;
  return rect;
};

SWDA_Window_SynthesisResult.prototype.resultNameRect = function () {
  let rect = new Rectangle();
  rect.x = this.contents.width / 2 - 150;
  rect.y = this.standardPadding() / 2;
  rect.width = 300;
  rect.height = this.fittingHeight(1);
  return rect;
};

SWDA_Window_SynthesisResult.prototype.resultEnemyInfoRect = function () {
  let rect = new Rectangle();
  rect.x = 0;
  rect.y = 0;
  rect.width = this.contents.width / 3;
  rect.height = this.contents.height;
  return rect;
};

SWDA_Window_SynthesisResult.prototype.resultEquipInfoRect = function () {
  let rect = new Rectangle();
  rect.x = (2 * this.contents.width) / 3;
  rect.y = 0;
  rect.width = this.contents.width / 3;
  rect.height = this.contents.height;
  return rect;
};

SWDA_Window_SynthesisResult.prototype.drawFailureSynthesis = function (
  rect,
  recipe1,
  recipe2,
  produce
) {
  if (
    !!recipe1 &&
    recipe2 &&
    produce &&
    !this.meetsSynthesisCondition(recipe1, recipe2, produce)
  )
    this.drawTextEx(
      this.failureSynthesisText(recipe1, recipe2, produce),
      rect.x,
      rect.y
    );
};

SWDA_Window_SynthesisResult.prototype.failureSynthesisText = function (
  recipe1,
  recipe2,
  produce
) {
  return CP.SynthesisManager.UI_SYNTHESIS_FAILURE_TEXT.format(
    recipe1.name,
    recipe2.name,
    produce.name
  );
};

//解析换行标记<br>
SWDA_Window_SynthesisResult.prototype.convertEscapeCharacters = function (
  text
) {
  text = text.replace(/<br>/g, "\n");
  return Window_Command.prototype.convertEscapeCharacters.call(this, text);
};

// 小c写的部分================================================================================

SWDA_Window_SynthesisResult.prototype.clearSucessFlag = function () {
  this._resultSuccess = false;
};

//合成是否成功，必须在执行synthesisResult函数之后【即真合成之后】才有结果
SWDA_Window_SynthesisResult.prototype.isSuccessful = function () {
  return !!this._resultSuccess;
};

//成功产物
SWDA_Window_SynthesisResult.prototype.successfulSynthesisResult = function () {
  return this._synthesisResult;
};

//成功判定
SWDA_Window_SynthesisResult.prototype.meetsSynthesisResult = function () {
  return Math.random() < 0.8;
};

//失败产物
//receipe1和receipe2是可交换的，都是data对象
//这个默认返回值是插件参数中的默认产物
SWDA_Window_SynthesisResult.prototype.failureResult = function (
  receipe1,
  receipe2
) {
  return CP.SynthesisManager.DEFAULT_PRODUCE.object();
};

setGlobal("SWDA_Window_SynthesisResult", SWDA_Window_SynthesisResult);
